/*
 * Author: nicolas.bredeche(@)lri.fr
 * Created on 14 janv. 2006
 * 
 */

package picoevo.ext.evolution;

import picoevo.core.evolution.ParameterSet;
import picoevo.core.evolution.SelectionOperator;
import picoevo.core.representation.Population;
import picoevo.core.representation.PopulationContainer;
import picoevo.core.representation.PopulationObject;
import picoevo.core.representation.PopulationView;

public class SelectionOperator_MuLambda extends SelectionOperator {

	public SelectionOperator_MuLambda() {
		super("MuLambda selection operator");
	}

	public SelectionOperator_MuLambda(String __name) {
		super(__name);
	}

	@Override
	public void performSelection(PopulationObject __population) {
		Population population = (Population) __population;

		// un population container permet de manipuler une liste qui contient
		// des *clones* des individus originaux (on peut theoriquement faire
		// n'importe quoi donc...)
		PopulationContainer newpop = new PopulationContainer(); // newpop va
		// contenir ma
		// liste
		// d'individus
		// pour la
		// prochaine
		// generation
		PopulationContainer newpopbuffer; // newpopbuffer va contenir des
		// bouts de la pop finale

		// TODO : revoir les methodes de PopulationContainer pour cloner
		// systematiquement les individus pass� en parametres. Sauf nom de
		// methode explicite!!!

		// un population viewer permet de manipuler une liste qui *pointe* sur
		// les individus originaux (attention a pas faire n'importe quoi)
		PopulationView populationView = SelectionOperator_SimpleRank.performSelectionView(population, (population.getTemplate()).getIntProperty("Mu")); // on
		// passe
		// par
		// un
		// view
		// car
		// parfois
		// on a
		// besoin
		// de
		// faire
		// un
		// traitement
		// avant
		// de
		// reintegrer
		// les
		// individus
		// on peut aussi les ajouter a la main... :
		// populationView.addIndividual(monIndividu);

		int nb = ((population.getTemplate()).getIntProperty("Lambda") + (population.getTemplate()).getIntProperty("Mu")) / (population.getTemplate()).getIntProperty("Mu");
		for (int j = 0; j != nb; j++) // emulate (muPLUSlambda)-ES ("PLUS"
		// should be made clearer later) TODO
		{
			newpopbuffer = new PopulationContainer(populationView);
			if (j != 0 || !(population.getTemplate()).getBooleanProperty("MuPlusLambda")) // premiere
			// passe
			// pour
			// les
			// mu
			// individus
			// que
			// l'on
			// conserve.
			// Ensuite
			// on
			// gerera
			// les
			// lambdas.
			{
				newpopbuffer.addOperatorList(__population.getVariationOperatorList());
				newpopbuffer.performVariations();
			}
			newpop.mergeWithContainer(newpopbuffer); // after this,
			// newpopbuffer does not
			// contain any
			// individuals.
		}

		// replace old population with the new frankensteined one
		population.renewPopulation(newpop); // after this, newpop does not
		// contain any individuals and
		// maxOnePop contains only new
		// individuals.
		// TODO : en impl�mentant mergeWithContainer en tant que
		// mergeWithPopulation dans Population,
	}
}
